﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Model;

namespace ConAppCore.Test
{
#pragma warning disable 8500
    unsafe internal class TestUnmanagedMemoryPointer
    {


        public TestUnmanagedMemoryPointer()
        {



        }


        public static void Test()
        {
            //TestRefSpan();
            //TestRefSpanPer();

            //TestSpanPoint1();
            //Console.WriteLine("--------------------------------------");
            //TestSpanPoint2();

            //TestSpanPara();
            //TestSpanExtendMethod();

            //TestPointerStruct testPointerStruct = new TestPointerStruct();
            //testPointerStruct.TestRefSpanPer();

            //TestVector();
            //TestIQUnmanagedMemoryPointer2();
            //TestUnmanagedMemoryPointer2();

            //TestPartReaderWriter();
            //TestReaderWriter();

            //TestPtrLimit();
            //Console.WriteLine("*********************************");
            //TestPtr();
            //Console.WriteLine("*********************************");
            //TestIQPtr();

            //TestCpopyPer();
            //TestDebugView();
            //TestUnmanagedMemoryPointerInitCount();

            //TestMemorySize();
            //TestMemorySize22();

            //TestDataReadAndWrite();

            using var poin = new UnmanagedMemoryPointer<byte>(UnitConverter.MByteToByte(1000));

            Console.ReadKey();
        }

        private static void TestDataReadAndWrite()
        {
            byte[] buffer = new byte[1000];
            using var ms = new MemoryStream(buffer);
            var reader = new BinaryReader(ms);
            var writer = new BinaryWriter(ms);

            short[] srcArr1 = new short[10];
            short[] dstArr1 = new short[10];
            for (int i = 0; i < srcArr1.Length; i++)
            {
                srcArr1[i] = (short)(1000 + i);
            }


            //ms.Position = 0;
            //for (int i = 0; i < srcArr1.Length; i++)
            //{
            //    writer.Write(srcArr1[i]);
            //}

            //ms.Position = 0;
            //fixed (short* dstArr1Ptr = dstArr1)
            //{
            //    reader.Read(new Span<byte>(dstArr1Ptr, dstArr1.Length * 2));
            //}

            ms.Position = 0;
            fixed (short* srcArr1Ptr = srcArr1)
            {
                writer.Write(new Span<byte>(srcArr1Ptr, srcArr1.Length * 2));
            }

            ms.Position = 0;
            for (int i = 0; i < srcArr1.Length; i++)
            {
                dstArr1[i] = reader.ReadInt16();
            }

        }

        private static void TestMemorySize22()
        {
            using var _bufferPointer = new UnmanagedMemoryPointer<byte>(1000);
            SpanZ<byte> data = _bufferPointer.GetSpanZ();

            using var stream = new UnmanagedMemoryStream(data.DataPtr, data.Length, data.Length, FileAccess.ReadWrite);
            var writer = new BinaryWriter(stream);

            writer.Write(1);
            writer.Write(2);
            writer.Write(3);

        }

        private static void TestMemorySize()
        {
            var _bufferPointer = new UnmanagedMemoryPointer<byte>(1536000000L);
            SpanZ<byte> iqData = _bufferPointer.GetSpanZ();

            int _demodDataByteLength = 256000;
            var OriginShortIQData = new UnmanagedMemoryPointer<byte>();
            OriginShortIQData.CheckSetLength(_demodDataByteLength);

            long offset = 0L;
            byte* srcPtr, dstPtr;
            byte[] arr = new byte[_demodDataByteLength];
            byte value = 0;

            while (iqData.LongLength - offset >= _demodDataByteLength)
            {
                srcPtr = iqData.DataPtr + offset;
                //dstPtr = OriginShortIQData.DataPtr;
                //for (int i = 0; i < _demodDataByteLength; i++)
                //{
                //    *dstPtr++ = *srcPtr++;
                //}

                for (int i = 0; i < _demodDataByteLength; i++)
                {
                    value = srcPtr[i];
                    //arr[i] = srcPtr[i];
                    //arr[i] = value++;
                }

                //UnmanagedMemoryPointerAbsZ.Copy(iqData.DataPtr + offset, OriginShortIQData.DataPtr, _demodDataByteLength);
                //UnmanagedMemoryPointerAbsZ.Move(iqData.DataPtr + offset, OriginShortIQData.DataPtr, _demodDataByteLength);
                //NativeMemory.Copy(iqData.DataPtr + offset, OriginShortIQData.DataPtr, (nuint)_demodDataByteLength);
                offset += _demodDataByteLength;
            }

            OriginShortIQData.Dispose();
            _bufferPointer.Dispose();
            Console.WriteLine("TestMemorySize any key exit..");



            Console.ReadKey();
        }


        private static void TestUnmanagedMemoryPointerInitCount()
        {
            using var pointer = new UnmanagedMemoryPointer<TestUnmanagedMemoryPointerStruct>(1);
            pointer.DataPtr->Length = 100;

            IntPtr ptr1 = (IntPtr)pointer.DataPtr;

            TestUnmanagedMemoryPointerStruct* ptr2 = (TestUnmanagedMemoryPointerStruct*)ptr1;
            int length = ptr2->Length;
        }

        private static void TestDebugView()
        {
            int count = 100;
            using var pointer = new UnmanagedMemoryPointer<int>(count);
            using var pointer1 = new UnmanagedMemoryPointer<Complex>(count);
            using var pointer2 = new IQUnmanagedMemoryPointer<int>(count);
            for (int i = 0; i < count; i++)
            {
                pointer[i] = i;
                pointer1[i] = new Complex(i, i + count);
                pointer2.SetI(i, i + 1);
                pointer2.SetQ(i, i + count);
            }


            SpanZ<int> span = pointer.GetSpanZ();
            Span<int> span02 = pointer.GetSpan();

            SpanZ<Complex> span1 = pointer1.GetSpanZ();
            Span<Complex> span12 = pointer1.GetSpan();
            IQSpanZ<int> span2 = pointer2.GetIQSpanZ();

            int a = count + span12.Length;
        }

        private static void TestCpopyPer()
        {
            int testCount = 20;
            for (int j = 0; j < testCount; j++)
            {
                PrimitiveTestCpopyPer();
                Console.WriteLine("--------------------------------------");
            }

            double time1 = _perList.Average(t => { return t.Item1; });
            double time2 = _perList.Average(t => { return t.Item2; });
            double time3 = _perList.Average(t => { return t.Item3; });
            double time4 = _perList.Average(t => { return t.Item4; });
            Console.WriteLine($"Average Array.Copy {testCount}:{time1}ms");
            Console.WriteLine($"Average NativeMemory.Copy {testCount}:{time2}ms");
            Console.WriteLine($"Average Arra-NativeMemory.Copy {testCount}:{time3}ms");
            Console.WriteLine($"Average Pinned Array.Copy {testCount}:{time4}ms");
        }

        private static List<Tuple<double, double, double, double>> _perList = new List<Tuple<double, double, double, double>>();

        private static void PrimitiveTestCpopyPer()
        {
            double time1, time2, time3, time4;

            byte[] buffer = new byte[2 * 600000];
            byte[] buffer2 = new byte[buffer.Length];
            int testCount = 10000;
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Restart();
            for (int i = 0; i < testCount; i++)
            {
                Array.Copy(buffer, 0, buffer2, 0, buffer.Length);
            }
            stopwatch.Stop();
            Console.WriteLine($"Array.Copy {testCount}:{stopwatch.Elapsed.TotalMilliseconds}ms");
            time1 = stopwatch.Elapsed.TotalMilliseconds;

            using var pointer1 = new UnmanagedMemoryPointer(sizeof(byte));
            using var pointer2 = new UnmanagedMemoryPointer(sizeof(byte));
            pointer1.CheckSetLength(buffer.Length);
            pointer2.CheckSetLength(buffer.Length);
            byte* ptr1 = (byte*)pointer1.DataPtr;
            byte* ptr2 = (byte*)pointer2.DataPtr;

            stopwatch.Restart();
            for (int i = 0; i < testCount; i++)
            {
                NativeMemory.Copy(ptr1, ptr2, (nuint)buffer.Length);
            }
            stopwatch.Stop();
            Console.WriteLine($"NativeMemory.Copy {testCount}:{stopwatch.Elapsed.TotalMilliseconds}ms");
            time2 = stopwatch.Elapsed.TotalMilliseconds;


            stopwatch.Restart();
            for (int i = 0; i < testCount; i++)
            {
                fixed (byte* ptr22 = buffer2)
                {
                    NativeMemory.Copy(ptr1, ptr22, (nuint)buffer.Length);
                }
            }
            stopwatch.Stop();
            Console.WriteLine($"Arra-NativeMemory.Copy {testCount}:{stopwatch.Elapsed.TotalMilliseconds}ms");
            time3 = stopwatch.Elapsed.TotalMilliseconds;


            GCHandle handle1 = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            GCHandle handle2 = GCHandle.Alloc(buffer2, GCHandleType.Pinned);
            byte[] buffer1Fix = (byte[])handle1.Target;
            byte[] buffer2Fix = (byte[])handle2.Target;
            stopwatch.Restart();
            for (int i = 0; i < testCount; i++)
            {
                Array.Copy(buffer1Fix, 0, buffer2Fix, 0, buffer1Fix.Length);
            }
            stopwatch.Stop();
            Console.WriteLine($"Pinned Array.Copy {testCount}:{stopwatch.Elapsed.TotalMilliseconds}ms");
            time4 = stopwatch.Elapsed.TotalMilliseconds;
            handle2.Free();

            _perList.Add(new Tuple<double, double, double, double>(time1, time2, time3, time4));
        }



        private static void TestSpanExtendMethod()
        {
            int count = 400;
            int haf = count / 2;
            using UnmanagedMemoryPointer<int> ptr = new UnmanagedMemoryPointer<int>(count);

            int value = 1;
            for (int i = 0; i < haf; i++)
            {
                ptr[i] = value++;
            }

            int value0 = ptr[0];

            Span<int> span = new Span<int>(ptr.DataPtr, count);
            for (int i = haf; i < count; i++)
            {
                span[i] = value++;
            }
            ptr.Length = count;


            var spanZ = ptr.GetSpanZ();
            var arrZ = spanZ.ToArray();
            var listZ = spanZ.ToList();

            Span<int>* spanPtr = &span;
            Console.WriteLine($"SrcSpan:{new IntPtr(spanPtr).ToString()},ptr:{new IntPtr(ptr.DataPtr).ToString()}");
            Console.WriteLine("----------------------------------------------------------------------");
            TestSpanExtendMethodSub(span, in span);
        }

        private static void TestSpanExtendMethodSub(Span<int> span, in Span<int> spanIn)
        {
            int* refPtr1 = UnmanagedMemoryHelper.GetSpanPointer(in span);
            Span<int>* spanPtr1 = &span;
            Console.WriteLine($"Span:{new IntPtr(spanPtr1).ToString()},ptr:{new IntPtr(refPtr1).ToString()}");
            Console.WriteLine("----------------------------------------------------------------------");

            int* refPtr2 = UnmanagedMemoryHelper.GetSpanPointer(in spanIn);
            fixed (Span<int>* spanPtr2 = &spanIn)
            {
                Console.WriteLine($"SpnIn:{new IntPtr(spanPtr2).ToString()},ptr:{new IntPtr(refPtr2).ToString()}");
            }
        }


        private static void TestSpanPara()
        {
            int count = 4;
            int haf = count / 2;
            using UnmanagedMemoryPointer<int> ptr = new UnmanagedMemoryPointer<int>(count);

            int value = 1;
            for (int i = 0; i < haf; i++)
            {
                ptr[i] = value++;
            }

            Span<int> span = new Span<int>(ptr.DataPtr, (int)ptr.Length);
            for (int i = haf; i < count; i++)
            {
                span[i] = value++;
            }


            Span<int>* spanPtr = &span;
            Console.WriteLine($"Span:{new IntPtr(spanPtr).ToString()},ptr:{new IntPtr(ptr.DataPtr).ToString()}");
            Console.WriteLine("*********************************");

            //函数调用时,in可写可不写,一样的结果.
            //函数定义时,参数不带in时,结构体为拷贝,带in时为变量只读引用传递
            TestSpanParaSub(span, in span);
            TestSpanParaSub(span, span);
        }

        private static void TestSpanParaSub(Span<int> span, in Span<int> spanIn)
        {
            int* refPtr1 = (int*)Unsafe.AsPointer(ref span[0]);
            int* refPtr2 = (int*)Unsafe.AsPointer(ref spanIn[0]);
            Span<int>* spanPtr1 = &span;
            fixed (Span<int>* spanPtr2 = &spanIn)
            {
                Console.WriteLine($"TestSpanParaSub Span:{new IntPtr(spanPtr1).ToString()},spanIn:{new IntPtr(spanPtr2).ToString()}");
                Console.WriteLine($"TestSpanParaSub refPtr1:{new IntPtr(refPtr1).ToString()},refInPtr1:{new IntPtr(refPtr2).ToString()}");
            }
        }

        private static void TestSpanPoint2()
        {
            int count = 4;
            int haf = count / 2;
            int[] arr = new int[count];

            int value = 1;
            for (int i = 0; i < haf; i++)
            {
                arr[i] = value++;
            }

            Span<int> span = new Span<int>(arr);
            for (int i = haf; i < count; i++)
            {
                span[i] = value++;
            }


            for (int i = 0; i < span.Length; i++)
            {
                Console.WriteLine(span[i]);
            }
            Console.WriteLine("*********************************");


            int* refPtr = (int*)Unsafe.AsPointer(ref span[0]);
            value = 10;
            Parallel.For(0, span.Length, (i) =>
            {
                refPtr[i] = value + i;
            });

            for (int i = 0; i < span.Length; i++)
            {
                Console.WriteLine(span[i]);
            }

            Console.WriteLine("*********************************");
            for (int i = 0; i < span.Length; i++)
            {
                Console.WriteLine(arr[i]);
            }
        }


        private static void TestSpanPoint1()
        {
            int count = 4;
            int haf = count / 2;
            using UnmanagedMemoryPointer<int> ptr = new UnmanagedMemoryPointer<int>(count);

            int value = 1;
            for (int i = 0; i < haf; i++)
            {
                ptr[i] = value++;
            }

            Span<int> span = new Span<int>(ptr.DataPtr, (int)ptr.Length);
            for (int i = haf; i < count; i++)
            {
                span[i] = value++;
            }


            for (int i = 0; i < span.Length; i++)
            {
                Console.WriteLine(span[i]);
            }
            Console.WriteLine("*********************************");


            //ref int value0 = ref span[0];
            //int* refPtr = (int*)Unsafe.AsPointer(ref value0);
            int* refPtr = (int*)Unsafe.AsPointer(ref span[0]);
            value = 10;
            Parallel.For(0, span.Length, (i) =>
            {
                refPtr[i] = value + i;
            });

            for (int i = 0; i < span.Length; i++)
            {
                Console.WriteLine(span[i]);
            }

            Console.WriteLine("*********************************");
            for (int i = 0; i < span.Length; i++)
            {
                Console.WriteLine(ptr.DataPtr[i]);
            }
        }





        private static void TestRefSpanPer()
        {
            //int testCount = 1000;
            //using var testObj = new TestUnmanagedMemoryPointerTestXX(10000);
            //testObj.TestStruct(testCount);
            //testObj.TestClass(testCount);
            //return;

            int count = 10000;
            int haf = count / 2;

            using UnmanagedMemoryPointer<int> ptr = new UnmanagedMemoryPointer<int>(count);

            int value = 1;
            for (int i = 0; i < haf; i++)
            {
                ptr[i] = value++;
            }
            //SpanZ<int> spanX = new SpanZ<int>(ptr.DataPtr, (int)ptr.Length);
            Span<int> spanX = new Span<int>(ptr.DataPtr, (int)ptr.Length);
            //SpanH<int> spanX = new SpanH<int>(ptr.DataPtr, (int)ptr.Length);
            for (int i = haf; i < count; i++)
            {
                spanX[i] = value++;
            }


            //SpanZ<int>* spanXPtr = &spanX;
            //Console.WriteLine(new IntPtr(spanXPtr).ToString());
            int testCount = 10000;
            Stopwatch stopwatch = new Stopwatch();


            //Console.WriteLine("SpanZ");
            //Console.WriteLine("SpanH");
            Console.WriteLine("Span");
            //Console.WriteLine("UnmanagedMemoryPointer");



            //stopwatch.Restart();
            for (int j = 0; j < testCount; j++)
            {
                int ret2 = TestRefSpanPerSub2(in spanX);
            }

            //stopwatch.Stop();
            //Console.WriteLine($"TestRefSpanPerSub2:{stopwatch.Elapsed.TotalMilliseconds}ms");



            stopwatch.Restart();
            for (int j = 0; j < testCount; j++)
            {
                int ret1 = TestRefSpanPerSub1(in spanX);
            }
            stopwatch.Stop();
            Console.WriteLine($"TestRefSpanPerSub1(in):{stopwatch.Elapsed.TotalMilliseconds}ms");

            //stopwatch.Restart();
            //for (int j = 0; j < testCount; j++)
            //{
            //    int ret2 = TestRefSpanPerSub2(ptr);
            //}

            //stopwatch.Stop();
            //Console.WriteLine($"TestRefSpanPerSub2:{stopwatch.Elapsed.TotalMilliseconds}ms");


            //stopwatch.Restart();
            //for (int j = 0; j < testCount; j++)
            //{
            //    int ret1 = TestRefSpanPerSub1(ptr);
            //}
            //stopwatch.Stop();
            //Console.WriteLine($"TestRefSpanPerSub1(in):{stopwatch.Elapsed.TotalMilliseconds}ms");

        }

        private static int TestRefSpanPerSub1(in Span<int> span)
        {
            int sum = 0;

            int* ptr = span.GetSpanPointer();
            Parallel.For(0, span.Length, (i) =>
            {
                Interlocked.Add(ref sum, ptr[i]);
            });

            //for (int i = 0; i < span.Length; i++)
            //{
            //    sum += span[i];
            //}

            //int sum = 0;
            //for (int i = 0; i < span.Length; i++)
            //{
            //    sum += span[i];
            //}
            return sum;
        }

        private static int TestRefSpanPerSub2(in Span<int> spanX)
        {
            int sum = 0;
            for (int i = 0; i < spanX.Length; i++)
            {
                sum += spanX[i];
            }

            return 0;
        }

        private static int TestRefSpanPerSub1(UnmanagedMemoryPointer<int> spanX)
        {
            int sum = 0;
            for (int i = 0; i < spanX.Length; i++)
            {
                sum += spanX[i];
            }

            return 0;
        }

        private static int TestRefSpanPerSub2(UnmanagedMemoryPointer<int> spanX)
        {
            int sum = 0;
            for (int i = 0; i < spanX.Length; i++)
            {
                sum += spanX[i];
            }

            return 0;
        }










        private static void TestRefSpan()
        {
            //int testCount = 1000;
            //using var testObj = new TestUnmanagedMemoryPointerTestXX(10000);
            //testObj.TestStruct(testCount);
            //testObj.TestClass(testCount);
            //return;

            int count = 8;
            int haf = count / 2;

            UnmanagedMemoryPointer<int> ptr = new UnmanagedMemoryPointer<int>(count);

            int value = 1;
            for (int i = 0; i < haf; i++)
            {
                ptr[i] = value++;
            }
            SpanZ<int> spanX = new SpanZ<int>(ptr.DataPtr, (int)ptr.Length);
            for (int i = haf; i < count; i++)
            {
                spanX[i] = value++;
            }

            Console.WriteLine("*************TestRefSpan********************");

            SpanZ<int>* spanXPtr = &spanX;
            Console.WriteLine(new IntPtr(spanXPtr).ToString());

            //fixed (UnmanagedMemoryPointer<int>* ptr2 = &ptr)
            //{
            //    Console.WriteLine(new IntPtr(ptr2).ToString());
            //}
            UnmanagedMemoryPointer<int>* ptr2 = &ptr;
            Console.WriteLine(new IntPtr(ptr2).ToString());



            for (int i = 0; i < spanX.Length; i++)
            {
                Console.WriteLine(spanX[i]);
            }

            TestRefSpanSub1(in spanX, in ptr, ptr2);

            ptr.Dispose();
        }

        private static void TestRefSpanSub1(in SpanZ<int> spanX, in UnmanagedMemoryPointer<int> ptr, UnmanagedMemoryPointer<int>* ptrX)
        {
            Console.WriteLine("************TestRefSpanSub1*********************");
            //SpanZ<int>* spanXPtr = &spanX;
            //Console.WriteLine(new IntPtr(spanXPtr).ToString());
            fixed (SpanZ<int>* spanXPtr = &spanX)
            {
                Console.WriteLine(new IntPtr(spanXPtr).ToString());
            }

            fixed (UnmanagedMemoryPointer<int>* ptr2 = &ptr)
            {
                Console.WriteLine(new IntPtr(ptr2).ToString());
            }

            Console.WriteLine(new IntPtr(ptrX).ToString());

            for (int i = 0; i < spanX.Length; i++)
            {
                Console.WriteLine(spanX[i]);
            }

            TestRefSpanSub2(in spanX, in ptr, ptrX);
        }

        private static void TestRefSpanSub2(in SpanZ<int> spanX, in UnmanagedMemoryPointer<int> ptr, UnmanagedMemoryPointer<int>* ptrX)
        {
            Console.WriteLine("************TestRefSpanSub2*********************");
            fixed (SpanZ<int>* spanXPtr = &spanX)
            {
                Console.WriteLine(new IntPtr(spanXPtr).ToString());
            }

            fixed (UnmanagedMemoryPointer<int>* ptr2 = &ptr)
            {
                Console.WriteLine(new IntPtr(ptr2).ToString());
            }

            Console.WriteLine(new IntPtr(ptrX).ToString());

            for (int i = 0; i < spanX.Length; i++)
            {
                Console.WriteLine(spanX[i]);
            }

        }



        private static void TestVector()
        {
            var vector1 = new Vector<ushort>(32);
            var vector2 = (Vector<ushort>)vector1;
        }

        private static void TestIQUnmanagedMemoryPointer2()
        {
            int count = 20;
            using var pointerByte = new IQUnmanagedMemoryPointer<byte>(count);
            using var pointerShort = new IQUnmanagedMemoryPointer(sizeof(short), count);


            Random rnd = new Random();
            //Span<short> spanI = pointerShort.GetGenericSpanIData<short>();
            //Span<short> spanQ = pointerShort.GetGenericSpanQData<short>();
            IQSpanZ<byte> iqSpan = pointerByte.GetIQSpanZ(count);
            for (short i = 0; i < count; i++)
            {
                iqSpan.SetI(i, (byte)rnd.Next(1, 10));
                iqSpan.SetQ(i, (byte)rnd.Next(1, 10));

                pointerShort.SetI<short>(i, (short)rnd.Next(1, 10));
                pointerShort.SetQ<short>(i, (short)rnd.Next(1, 10));
            }
            pointerShort.Length = count;
            pointerByte.Length = count;

            Console.WriteLine("-------------------------");
            short* iDataPtr = (short*)pointerShort.IDataPtr;
            short* qDataPtr = (short*)pointerShort.QDataPtr;
            for (int i = 0; i < pointerShort.Length; i++)
            {
                Console.WriteLine($"{*iDataPtr++},{*qDataPtr}        {pointerByte.GetI(i)},{pointerByte.GetQ(i)}");
            }


            //pointerShort.Fill((short)111);
            //pointerByte.Fill((byte)222);
            pointerShort.Clear();
            pointerByte.Clear();

            Console.WriteLine("-------fill------------------");

            iDataPtr = (short*)pointerShort.IDataPtr;
            qDataPtr = (short*)pointerShort.QDataPtr;
            IQSpanZ<byte> iqSpan2 = pointerByte.GetIQSpanZ();
            for (int i = 0; i < pointerShort.Length; i++)
            {
                Console.WriteLine($"{*iDataPtr++},{*qDataPtr}        {iqSpan2.GetI(i)},{iqSpan2.GetQ(i)}");
            }

        }

        private static void TestUnmanagedMemoryPointer2()
        {
            int count = 20;
            using var pointerShort = new UnmanagedMemoryPointer(sizeof(short), count);
            using var pointerByte = new UnmanagedMemoryPointer<byte>(count);



            Random rnd = new Random();
            SpanZ<short> span = pointerShort.GetSpanZ<short>();
            for (short i = 0; i < count; i++)
            {
                span[i] = (short)rnd.Next(1, 10);
                pointerByte[i] = (byte)rnd.Next(1, 10);
            }
            pointerShort.Length = count;
            pointerByte.Length = count;

            Console.WriteLine("-------------------------");
            short* ptr = (short*)pointerShort.DataPtr;
            for (int i = 0; i < pointerShort.Length; i++)
            {
                Console.WriteLine($"{*ptr++}        {pointerByte[i]}");
            }


            pointerShort.Fill((short)111);
            pointerByte.Fill((byte)222);
            //pointerShort.Fill2(111);
            //pointerByte.Fill2(222);
            Console.WriteLine("-------fill------------------");

            ptr = (short*)pointerShort.DataPtr;
            for (int i = 0; i < pointerShort.Length; i++)
            {
                Console.WriteLine($"{*ptr++}        {pointerByte[i]}");
            }

            //short[] arr = new short[pointerShort.Length];
            //fixed (short* dest = arr)
            //{
            //    NativeMemory.Copy(pointerShort.DataPtr, dest, new nuint((uint)(pointerShort.Length * sizeof(short))));
            //}
            //for (int i = 0; i < pointerShort.Length; i++)
            //{
            //    Console.WriteLine($"{arr[i]}        {pointerByte[i]}");
            //}

        }


        private static void TestPartReaderWriter()
        {
            int blockSize = sizeof(int);
            int count = 10;
            using var ptrItem = new UnmanagedMemoryPointer(blockSize, count);


            int offset = 3, eleCount = 4;
            long byteLength = eleCount * blockSize;
            using var memoryStream = new UnmanagedMemoryStream((byte*)((int*)ptrItem.DataPtr + offset), byteLength, byteLength, FileAccess.ReadWrite);
            var writer = new BinaryWriter(memoryStream);
            for (int i = 0; i < eleCount; i++)
            {
                writer.Write(i);
            }

            memoryStream.Position = 0L;
            var reader = new BinaryReader(memoryStream);
            for (int i = 0; i < eleCount; i++)
            {
                Console.WriteLine(reader.ReadInt32());
            }


            //Span<int> spanBuffer = new Span<int>((int*)ptrItem.DataPtr + offset, eleCount);
            //var value1 = spanBuffer[0];
            //spanBuffer[0] = 1;


            Span<byte> spanBuffer22 = new Span<byte>((int*)ptrItem.DataPtr + offset, (int)byteLength);
            //Socket socket = null;
            //socket.Receive(spanBuffer22);
            //socket.Send(spanBuffer22);
        }

        private static void TestReaderWriter()
        {
            int blockSize = sizeof(int);
            int count = 10;
            using var ptrItem = new UnmanagedMemoryPointer(blockSize, count);

            long byteLength = ptrItem.Length * blockSize;
            using var memoryStream = new UnmanagedMemoryStream((byte*)ptrItem.DataPtr, byteLength, byteLength, FileAccess.ReadWrite);
            var writer = new BinaryWriter(memoryStream);
            for (int i = 0; i < count; i++)
            {
                writer.Write(i);
            }

            memoryStream.Position = 0L;
            var reader = new BinaryReader(memoryStream);
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine(reader.ReadInt32());
            }
        }


        private static void TestPtrLimit()
        {
            int blockSize = 1000000;//MB
            using var ptrItem = new UnmanagedMemoryPointer(blockSize);

            //long eleCount = 30;
            long eleCount = 30 * 1024 * 1024;
            if (ptrItem.TryCheck(eleCount))
            {
                Console.WriteLine($"申请成功");
            }
            else
            {
                Console.WriteLine($"申请失败,{ptrItem.Error}");
            }
        }


        private static void TestIQPtr()
        {
            int count = 400;
            using var ptrItem = new IQUnmanagedMemoryPointer(sizeof(short), count);

            short* shortIDataPtr = (short*)ptrItem.IDataPtr;
            short* shortQDataPtr = (short*)ptrItem.QDataPtr;

            for (int i = 0; i < count; i++)
            {
                *shortIDataPtr = (short)(i + 1);
                shortIDataPtr++;

                *shortQDataPtr = (short)(i * 2 + 1);
                shortQDataPtr++;
            }

            shortIDataPtr = (short*)ptrItem.IDataPtr;
            shortQDataPtr = (short*)ptrItem.QDataPtr;
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine(string.Format("{0}    {1} {2}", i + 1, *shortIDataPtr, *shortQDataPtr));
                shortIDataPtr++;
                shortQDataPtr++;
            }

            Console.WriteLine("-----------------");
            IQSpanZ<short> iqSpan = ptrItem.GetIQSpanZ<short>(count);


            count = 6;
            ptrItem.Check(count);

            shortIDataPtr = (short*)ptrItem.IDataPtr;
            shortQDataPtr = (short*)ptrItem.QDataPtr;
            for (int i = 0; i < count; i++)
            {
                *shortIDataPtr = (short)((i + 1) * 10);
                shortIDataPtr++;

                *shortQDataPtr = (short)((i * 2 + 1) * 10);
                shortQDataPtr++;
            }

            shortIDataPtr = (short*)ptrItem.IDataPtr;
            shortQDataPtr = (short*)ptrItem.QDataPtr;
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine(string.Format("{0}    {1} {2}", i + 1, *shortIDataPtr, *shortQDataPtr));
                shortIDataPtr++;
                shortQDataPtr++;
            }



        }

        private static void TestPtr()
        {
            int count = 4;
            var ptrItem = new UnmanagedMemoryPointer(sizeof(short), count);

            short* shortPtr = (short*)ptrItem.DataPtr;
            for (int i = 0; i < count; i++)
            {
                *shortPtr = (short)(i + 1);
                shortPtr++;
            }

            shortPtr = (short*)ptrItem.DataPtr;
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine(string.Format("{0}    {1}", i + 1, *shortPtr));
                shortPtr++;
            }

            Console.WriteLine("-----------------");
            count = 6;
            ptrItem.Check(count);

            shortPtr = (short*)ptrItem.DataPtr;
            for (int i = 0; i < count; i++)
            {
                *shortPtr = (short)((i + 1) * 10);
                shortPtr++;
            }

            shortPtr = (short*)ptrItem.DataPtr;
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine(string.Format("{0}    {1}", i + 1, *shortPtr));
                shortPtr++;
            }

            ptrItem.Dispose();
        }

    }


    unsafe public struct TestUnmanagedMemoryPointerStruct
    {
        public int Length;

        public short* Value;
    }




}
